/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package wekimini.learning;

import java.awt.CardLayout;
import java.text.DecimalFormat;
import java.util.logging.Logger;
import wekimini.util.Util;

/**
 *
 * @author rebecca
 */
public class SVMEditorPanel extends LearningModelBuilderEditorPanel {

    private static final Logger logger = Logger.getLogger(SVMEditorPanel.class.getName());
    private static final DecimalFormat dFormat = new DecimalFormat("#.###");

    /**
     * Creates new form AdaBoostEditorPanel
     */
    public SVMEditorPanel() {
        initComponents();
    }

    public SVMEditorPanel(SVMModelBuilder mb) {
        initComponents();
        if (mb.getKernelType() == SVMModelBuilder.KernelType.LINEAR) {
            setLinear(mb);
        } else if (mb.getKernelType() == SVMModelBuilder.KernelType.POLYNOMIAL) {
            setPoly(mb);
        } else {
            setRBF(mb);
        }
    }

    private void setLinear(SVMModelBuilder mb) {
        comboKernel.setSelectedIndex(0);
        textC.setText(dFormat.format(mb.getComplexity()));
    }

    private void setPoly(SVMModelBuilder mb) {
        comboKernel.setSelectedIndex(1);
        textC.setText(dFormat.format(mb.getComplexity()));
        textPolyExponent.setText(dFormat.format(mb.getPolyExponent()));
        checkPolyLower.setSelected(mb.getPolyUseLowerOrder());
    }

    private void setRBF(SVMModelBuilder mb) {
        comboKernel.setSelectedIndex(2);
        textC.setText(dFormat.format(mb.getComplexity()));
        textRbfGamma.setText(dFormat.format(mb.getRbfGamma()));
    }

    @Override
    public boolean validateForm() {
        try {
            double d = Double.parseDouble(textC.getText());
            if (d <= 0) {
                Util.showPrettyErrorPane(this, "Complexity must be a number greater than 0");
                return false;
            }
        } catch (NumberFormatException ex) {
            Util.showPrettyErrorPane(this, "Complexity must be a number greater than 0");
            return false;
        }

        if (comboKernel.getSelectedIndex() == 0) {
            //Linear
            return true;
        } else if (comboKernel.getSelectedIndex() == 1) {
            //Poly
            try {
                double d = Double.parseDouble(textPolyExponent.getText());
                if (d <= 0) {
                    Util.showPrettyErrorPane(this, "Exponent must be a number greater than 0");
                    return false;
                } else { 
                    return true;
                }
            } catch (NumberFormatException ex) {
                Util.showPrettyErrorPane(this, "Exponent must be a number greater than 0");
                return false;
            }
        } else {
            //RBF
            try {
                double d = Double.parseDouble(textRbfGamma.getText());
                if (d <= 0) {
                    Util.showPrettyErrorPane(this, "Gamma must be a number greater than 0");
                    return false;
                } else { 
                    return true;
                }
            } catch (NumberFormatException ex) {
                Util.showPrettyErrorPane(this, "Gamma must be a number greater than 0");
                return false;
            }
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel2 = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        comboKernel = new javax.swing.JComboBox();
        jLabel3 = new javax.swing.JLabel();
        textC = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        panelKernelParent = new javax.swing.JPanel();
        panelPolyKernel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        checkPolyLower = new javax.swing.JCheckBox();
        textPolyExponent = new javax.swing.JTextField();
        panelLinearKernel = new javax.swing.JPanel();
        panelRBFKernel = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        textRbfGamma = new javax.swing.JTextField();
        panelOtherKernel = new javax.swing.JPanel();

        setBackground(new java.awt.Color(255, 255, 255));

        jPanel2.setBackground(new java.awt.Color(255, 255, 255));
        jPanel2.setLayout(new javax.swing.BoxLayout(jPanel2, javax.swing.BoxLayout.Y_AXIS));

        jPanel1.setBackground(new java.awt.Color(255, 255, 255));

        comboKernel.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Linear", "Polynomial", "RBF" }));
        comboKernel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                comboKernelActionPerformed(evt);
            }
        });

        jLabel3.setText("Kernel:");

        textC.setText("1.0");

        jLabel4.setText("Complexity constant:");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(comboKernel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jLabel4)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(textC, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(comboKernel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(textC, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
        );

        jPanel2.add(jPanel1);

        panelKernelParent.setBackground(new java.awt.Color(255, 255, 255));
        panelKernelParent.setLayout(new java.awt.CardLayout());

        panelPolyKernel.setBackground(new java.awt.Color(255, 255, 255));

        jLabel1.setText("Exponent:");

        checkPolyLower.setText("Use lower-order terms");
        checkPolyLower.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
        checkPolyLower.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                checkPolyLowerActionPerformed(evt);
            }
        });

        textPolyExponent.setText("2.0");

        javax.swing.GroupLayout panelPolyKernelLayout = new javax.swing.GroupLayout(panelPolyKernel);
        panelPolyKernel.setLayout(panelPolyKernelLayout);
        panelPolyKernelLayout.setHorizontalGroup(
            panelPolyKernelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelPolyKernelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(textPolyExponent, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addComponent(checkPolyLower)
        );
        panelPolyKernelLayout.setVerticalGroup(
            panelPolyKernelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelPolyKernelLayout.createSequentialGroup()
                .addGroup(panelPolyKernelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(textPolyExponent, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkPolyLower))
        );

        panelKernelParent.add(panelPolyKernel, "polynomial");

        panelLinearKernel.setBackground(new java.awt.Color(255, 255, 255));

        javax.swing.GroupLayout panelLinearKernelLayout = new javax.swing.GroupLayout(panelLinearKernel);
        panelLinearKernel.setLayout(panelLinearKernelLayout);
        panelLinearKernelLayout.setHorizontalGroup(
            panelLinearKernelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 213, Short.MAX_VALUE)
        );
        panelLinearKernelLayout.setVerticalGroup(
            panelLinearKernelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 63, Short.MAX_VALUE)
        );

        panelKernelParent.add(panelLinearKernel, "linear");

        panelRBFKernel.setBackground(new java.awt.Color(255, 255, 255));

        jLabel2.setText("Gamma:");

        textRbfGamma.setText(".01");

        javax.swing.GroupLayout panelRBFKernelLayout = new javax.swing.GroupLayout(panelRBFKernel);
        panelRBFKernel.setLayout(panelRBFKernelLayout);
        panelRBFKernelLayout.setHorizontalGroup(
            panelRBFKernelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelRBFKernelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(textRbfGamma, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(106, Short.MAX_VALUE))
        );
        panelRBFKernelLayout.setVerticalGroup(
            panelRBFKernelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelRBFKernelLayout.createSequentialGroup()
                .addGroup(panelRBFKernelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(textRbfGamma, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(35, Short.MAX_VALUE))
        );

        panelKernelParent.add(panelRBFKernel, "rbf");

        panelOtherKernel.setBackground(new java.awt.Color(255, 255, 255));

        javax.swing.GroupLayout panelOtherKernelLayout = new javax.swing.GroupLayout(panelOtherKernel);
        panelOtherKernel.setLayout(panelOtherKernelLayout);
        panelOtherKernelLayout.setHorizontalGroup(
            panelOtherKernelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 213, Short.MAX_VALUE)
        );
        panelOtherKernelLayout.setVerticalGroup(
            panelOtherKernelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 63, Short.MAX_VALUE)
        );

        panelKernelParent.add(panelOtherKernel, "other");

        jPanel2.add(panelKernelParent);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void checkPolyLowerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkPolyLowerActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_checkPolyLowerActionPerformed

    private void comboKernelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboKernelActionPerformed
        int i = comboKernel.getSelectedIndex();
        setKernelIndex(i);
    }//GEN-LAST:event_comboKernelActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox checkPolyLower;
    private javax.swing.JComboBox comboKernel;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel panelKernelParent;
    private javax.swing.JPanel panelLinearKernel;
    private javax.swing.JPanel panelOtherKernel;
    private javax.swing.JPanel panelPolyKernel;
    private javax.swing.JPanel panelRBFKernel;
    private javax.swing.JTextField textC;
    private javax.swing.JTextField textPolyExponent;
    private javax.swing.JTextField textRbfGamma;
    // End of variables declaration//GEN-END:variables

    //Assumes form is valid
    @Override
    public SVMModelBuilder buildFromPanel() {
        SVMModelBuilder mb = new SVMModelBuilder();
        mb.setComplexity(Double.parseDouble(textC.getText()));
        if (comboKernel.getSelectedIndex() == 0) {
            //Linear
            mb.setLinearKernel();
        } else if (comboKernel.getSelectedIndex() == 1) {
            //Poly
            double p = Double.parseDouble(textPolyExponent.getText());
            boolean u = checkPolyLower.isSelected();
            mb.setPolyKernel(p, u);
        } else {
            //RBF
            double g = Double.parseDouble(textRbfGamma.getText());
            mb.setRbfKernel(g);
        }
        return mb;
    }

    private void setKernelIndex(int i) {
        CardLayout l = (CardLayout) panelKernelParent.getLayout();
        if (i == 0) {
            l.show(panelKernelParent, "linear");
        } else if (i == 1) {
            l.show(panelKernelParent, "polynomial");
        } else if (i == 2) {
            l.show(panelKernelParent, "rbf");
        } else {
            l.show(panelKernelParent, "other");
        }
    }
}
